package com.gopay.solution.domain.bo.impl;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import com.gopay.common.constants.poundage.FeeDtlStatus;
import com.gopay.common.constants.poundage.FeeType;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.domain.poundage.PoundageReq;
import com.gopay.common.domain.solution.GpComReq;
import com.gopay.common.util.NumberUtils;
import com.gopay.solution.domain.po.SolutionRuleDtl;
import com.gopay.solution.domain.po.SsGpComConfDtl;
import com.gopay.solution.domain.vo.Event;
import com.gopay.solution.domain.vo.Result;

/**
 * 佣金方案规则执行器
 * 
 * @SsGpComSoluRuleExecutor.java
 * @author Ryan
 * @2014年4月18日 下午3:36:07 www.gopay.com.cn Inc.All rights reserved.
 */
@Service(value = "ssGpComSoluRuleExecutor")
public class SsGpComSoluRuleExecutor extends AbstractSolutionRuleExecutor {

    private static final String SUCC_CODE = "1";
    private static final String FAIL_CODE = "0";

    @Override
    public Result execute(List<SolutionRuleDtl> rules, Event event) {

       
        Result res = new Result();
        res.setSolved(false);
        res.setFailedReason("");
        res.setDetail(null);

        if (null == rules || rules.isEmpty()) {
            res.setFailedReason("查询不到佣金方案记录");
            return res;
        }

        Serializable input = event.getDetail();

        GpComReq req = (GpComReq) input;
        BigDecimal amt = req.getAmount();
        BigDecimal feeAmt = req.getFeeAmount();

        for (SolutionRuleDtl rule : rules) {

            String isValidate = validateAmt((SsGpComConfDtl) rule, amt, feeAmt);
            if (null != isValidate) {
                res.setDetail(isValidate);
                break;
            }else{
                res.setDetail("0");
                break;
            }
        }

        

        if (null != res.getDetail()) {
            res.setSolved(true);
        }
        return res;
    }

    /**
     * 计费方式
     * 
     * 0 - 年费 1 - 订单成交金额区间比率收费 2 - 按笔收费 3 - 订单成交金额区间定额收费
     * 
     * @param dtl
     * @param amt
     * @param feeAmt
     * @return 0 --failtrue 1- success
     */
    private String validateAmt(SsGpComConfDtl dtl, BigDecimal amt, BigDecimal feeAmt) {

        if (amt.compareTo(new BigDecimal(0.00)) > 0 && !StringUtils.equals(dtl.getDtlStatus(), FeeDtlStatus._00.value)) {
            return null;
        }

        BigDecimal fee = new BigDecimal("0.00");

        

        String feeType_ = dtl.getFeeType();
        if (null == feeType_) {
            logger.error("无效的feeType：" + dtl.toString());
            return FAIL_CODE;
        }

        // 不收费
        if (feeType_.equals(FeeType._N.value)) {
            return SUCC_CODE;
        }
        // 按笔
        if (feeType_.equals(FeeType._2.value)) {
            fee.add(new BigDecimal(dtl.getCalExp()));
            if (feeAmt.compareTo(fee) == 0) {
                return SUCC_CODE;
            } else {
                return FAIL_CODE;
            }
        }

        // 比例
        if (feeType_.equals(FeeType._1.value)) {
            String[] ranges = StringUtils.split(dtl.getCalExp(), '#');
            for (String range : ranges) {
                String[] param = StringUtils.split(range, '-');
                BigDecimal start = new BigDecimal(param[0]);// 起始
                String endStr = param[1];// 结束
                BigDecimal end = StringUtils.equals("+", endStr) ? new BigDecimal(String.valueOf(Long.MAX_VALUE))
                        : new BigDecimal(endStr);
                if (amt.compareTo(start) >= 0 && amt.compareTo(end) < 0) {
                    BigDecimal sacle = new BigDecimal(param[2]);// 百分比
                    if (sacle.compareTo(NumberUtils.getZero()) > 0) {
                        // amt*sacle/100
                        fee = amt.multiply(sacle).divide(new BigDecimal(100));
                    }

                    BigDecimal min = new BigDecimal(param[3]);
                    BigDecimal max = new BigDecimal(param[4]);
                    if (fee.compareTo(min) < 0) {
                        fee = min;
                    }
                    if (fee.compareTo(max) > 0) {
                        fee = max;
                    }
                    if (null == fee || fee.compareTo(NumberUtils.getZero()) < 0) {
                        fee = NumberUtils.getZero();
                    }
                    
                    if(fee.compareTo(feeAmt) >=0){
                        return SUCC_CODE;
                    }else {
                        return FAIL_CODE;
                    }
                }
            }

            logger.error("佣金计算错误，amt: " + amt + ", calExp: " + dtl.getCalExp());
            return null;
        }
        // 定额
        if (feeType_.equals(FeeType._3.value)) {
            String[] ranges = StringUtils.split(dtl.getCalExp(), '#');
            for (String range : ranges) {
                String[] param = StringUtils.split(range, '-');
                BigDecimal start = new BigDecimal(param[0]);// 起始值
                String endStr = param[1];
                BigDecimal end = StringUtils.equals("+", endStr) ? new BigDecimal(String.valueOf(Long.MAX_VALUE))
                        : new BigDecimal(endStr);// 结束值
                if (amt.compareTo(start) >= 0 && amt.compareTo(end) < 0) {
                    fee = fee.add(new BigDecimal(param[2]));
                    
                    //判断按交易额和比例计算出来的金额，如果计算出来的金额大于上传的费用金额，返回 “1” ，否则返回 “0”
                    if(fee.compareTo(feeAmt) >=0){
                        return SUCC_CODE;
                    }else {
                        return FAIL_CODE;
                    }
                }
            }
            logger.error("佣金计算错误，amt: " + amt + ", calExp: " + dtl.getCalExp());
        }
        return null;
    }
}
